Passed
Branch master (cf07e3)
by Rafael S.
01:53
created

index.js ➔ getChunkSize_   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
/*
2
 * riff-chunks
3
 * Read and write the chunks of RIFF and RIFX files.
4
 * Copyright (c) 2017-2018 Rafael da Silva Rocha.
5
 * https://github.com/rochars/riff-chunks
6
 *
7
 */
8
9
/** @private */
10
const byteData = require("byte-data");
11
/** @private */
12
const uInt32_ = {"bits": 32};
13
/** @private */
14
const fourCC_ = {"bits": 32, "char": true};
15
16
/**
17
 * Write the bytes of a RIFF/RIFX file.
18
 * @param {!Object} chunks A structure like the return of riffChunks.read().
19
 * @return {!Array<number>|Uint8Array} The bytes as Uint8Array when chunkId is
20
 *      "RIFF" or "RIFX" or the chunk bytes as Array<number> when chunkId is "LIST".
21
 */
22
function write(chunks) {
23
    uInt32_["be"] = chunks["chunkId"] == "RIFX";
24
    let bytes =
25
        byteData.pack(chunks["chunkId"], fourCC_).concat(
26
                byteData.pack(chunks["chunkSize"], uInt32_),
27
                byteData.pack(chunks["format"], fourCC_),
28
                writeSubChunks_(chunks["subChunks"])
29
            );
30
    if (chunks["chunkId"] == "RIFF" || chunks["chunkId"] == "RIFX" ) {
31
        bytes = new Uint8Array(bytes);
32
    }
33
    return bytes;
34
}
35
36
/**
37
 * Get the chunks of a RIFF/RIFX file.
38
 * @param {!Uint8Array|!Array<number>} buffer The file bytes.
39
 * @return {!Object} The chunk.
40
 */
41
function read(buffer) {
42
    buffer = [].slice.call(buffer);
43
    let chunkId = getChunkId_(buffer, 0);
44
    uInt32_["be"] = chunkId == "RIFX";
45
    return {
46
        "chunkId": chunkId,
47
        "chunkSize": getChunkSize_(buffer, 0),
48
        "format": byteData.unpack(buffer.slice(8, 12), fourCC_),
49
        "subChunks": getSubChunks_(buffer)
50
    };
51
}
52
53
/**
54
 * Write the sub chunks of a RIFF file.
55
 * @param {!Array<!Object>} chunks The chunks.
56
 * @return {!Array<number>} The chunk bytes.
57
 * @private
58
 */
59
function writeSubChunks_(chunks) {
60
    let subChunks = [];
61
    let i = 0;
62
    while (i < chunks.length) {
63
        if (chunks[i]["chunkId"] == "LIST") {
64
            subChunks = subChunks.concat(write(chunks[i]));
65
        } else {
66
            subChunks = subChunks.concat(
67
                byteData.pack(chunks[i]["chunkId"], fourCC_),
68
                byteData.pack(chunks[i]["chunkSize"], uInt32_),
69
                chunks[i]["chunkData"]
70
            );
71
        }
72
        i++;
73
    }
74
    return subChunks;
75
}
76
77
/**
78
 * Get the sub chunks of a RIFF file.
79
 * @param {!Uint8Array|!Array<number>} buffer the RIFF file bytes.
80
 * @return {!Array<Object>} The subchunks of a RIFF/RIFX or LIST chunk.
81
 * @private
82
 */
83
function getSubChunks_(buffer) {
84
    let chunks = [];
85
    let i = 12;
86
    while(i < buffer.length) {
87
        chunks.push(getSubChunk_(buffer, i));
88
        i += 8 + chunks[chunks.length - 1]["chunkSize"];
89
    }
90
    return chunks;
91
}
92
93
/**
94
 * Get a sub chunk from a RIFF file.
95
 * @param {!Uint8Array|!Array<number>} buffer the RIFF file bytes.
96
 * @param {!number} index The start index of the chunk.
97
 * @return {!Object} A subchunk of a RIFF/RIFX or LIST chunk.
98
 * @private
99
 */
100
function getSubChunk_(buffer, index) {
101
    let chunk = {
102
        "chunkId": getChunkId_(buffer, index),
103
        "chunkSize": getChunkSize_(buffer, index),
104
        "subChunks": [],
105
        "chunkData": []
106
    };
107
    if (chunk["chunkId"] == "LIST") {
108
        chunk["format"] = byteData.unpack(buffer.slice(8, 12), fourCC_);
109
        chunk["subChunks"] = getSubChunks_(
110
            buffer.slice(index, index + chunk["chunkSize"]));
111
    } else {
112
        chunk["chunkData"] = buffer.slice(
113
            index + 8, index + 8 + chunk["chunkSize"]);
114
    }
115
    return chunk;
116
}
117
118
/**
119
 * Return the fourCC_ of a chunk.
120
 * @param {!Uint8Array|!Array<number>} buffer the RIFF file bytes.
121
 * @param {!number} index The start index of the chunk.
122
 * @return {!string} The id of the chunk.
123
 * @private
124
 */
125
function getChunkId_(buffer, index) {
126
    return byteData.unpack(buffer.slice(index, index + 4), fourCC_);
127
}
128
129
/**
130
 * Return the size of a chunk.
131
 * @param {!Uint8Array|!Array<number>} buffer the RIFF file bytes.
132
 * @param {!number} index The start index of the chunk.
133
 * @return {!number} The size of the chunk without the id and size fields.
134
 * @private
135
 */
136
function getChunkSize_(buffer, index) {
137
    return byteData.unpack(buffer.slice(index + 4, index + 8), uInt32_);
138
}
139
140
module.exports.read = read;
141
module.exports.write = write;
142